home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / game / think / AmiChess.lha / AmiChess / src / atak.c next >
C/C++ Source or Header  |  2002-10-31  |  7KB  |  341 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "common.h"
  4.  
  5. const short raybeg[7]={0,0,0,0,4,0,0};
  6. const short rayend[7]={0,0,0,4,8,8,0};
  7.  
  8. short SqAtakd(short sq,short side)
  9. {
  10. BitBoard *a,b,*c,d,blocker;
  11. short t;
  12. a=board.b[side];
  13. if(a[knight]&MoveArray[knight][sq]) return true;
  14. if(a[king]&MoveArray[king][sq]) return true;
  15. if(a[pawn]&MoveArray[ptype[1^side]][sq]) return true;
  16. c=FromToRay[sq];
  17. blocker=board.blocker;
  18. b=(a[bishop]|a[queen])&MoveArray[bishop][sq];
  19. d=~b&blocker;
  20. while(b)
  21.     {
  22.     t=leadz(b);
  23.     if(!(c[t]&d)) return true;
  24.     CLEARBIT(b,t);
  25.     }
  26. b=(a[rook]|a[queen])&MoveArray[rook][sq];
  27. d=~b&blocker;
  28. while(b)
  29.     {
  30.     t=leadz(b);
  31.     if(!(c[t]&d)) return true;
  32.     CLEARBIT(b,t);
  33.     }
  34. return false;
  35. }
  36.  
  37. void GenAtaks()
  38. {
  39. short side,sq;
  40. BitBoard *a,b,*t,*a0;
  41. memset(Ataks,0,sizeof(Ataks));
  42. for(side=white;side<=black;side++)
  43.     {
  44.     a=board.b[side];
  45.     t=&Ataks[side][knight];
  46.     b=a[knight];
  47.     while(b)
  48.         {
  49.         sq=leadz(b);
  50.         CLEARBIT(b,sq);
  51.         *t|=MoveArray[knight][sq];
  52.         }
  53.     t=&Ataks[side][bishop];
  54.     b=a[bishop];
  55.     while(b)
  56.         {
  57.         sq=leadz(b);
  58.         CLEARBIT(b,sq);
  59.         *t|=BishopAttack(sq);
  60.         }
  61.     t=&Ataks[side][rook];
  62.     b=a[rook];
  63.     while(b)
  64.         {
  65.         sq=leadz(b);
  66.         CLEARBIT(b,sq);
  67.         *t|=RookAttack(sq);
  68.         }
  69.     t=&Ataks[side][queen];
  70.     b=a[queen];
  71.     while(b)
  72.         {
  73.         sq=leadz(b);
  74.         CLEARBIT(b,sq);
  75.         *t|=QueenAttack(sq);
  76.         }
  77.     t=&Ataks[side][king];
  78.     b=a[king];
  79.     while(b)
  80.         {
  81.         sq=leadz(b);
  82.         CLEARBIT(b,sq);
  83.         *t|=MoveArray[king][sq];
  84.         }
  85.     t=&Ataks[side][pawn];
  86.     if(side==white)
  87.         {
  88.         b=board.b[white][pawn]&~FileBit[0];
  89.         *t|=(b>>7);
  90.         b=board.b[white][pawn]&~FileBit[7];
  91.         *t|=(b>>9);
  92.         }
  93.     else
  94.         {
  95.         b=board.b[black][pawn]&~FileBit[0];
  96.         *t|=(b<<9);
  97.         b=board.b[black][pawn]&~FileBit[7];
  98.         *t|=(b<<7);
  99.         }
  100.     a0=Ataks[side];
  101.     a0[0]=a0[pawn]|a0[knight]|a0[bishop]|a0[rook]|a0[queen]|a0[king];
  102.     }
  103. }
  104.  
  105.  
  106. BitBoard AttackTo(short sq,short side)
  107. {
  108. BitBoard *a,b,*c,e,blocker;
  109. short t;
  110. a=board.b[side];
  111. e=(a[knight]&MoveArray[knight][sq]);    
  112. e|=(a[king]&MoveArray[king][sq]);    
  113. e|=(a[pawn]&MoveArray[ptype[1^side]][sq]);
  114. c=FromToRay[sq];
  115. blocker=board.blocker;
  116. b=(a[bishop]|a[queen])&MoveArray[bishop][sq];
  117. while(b)
  118.     {
  119.     t=leadz(b);
  120.     CLEARBIT(b,t);
  121.     if(!(c[t]&blocker&NotBitPosArray[t]))
  122.     e|=BitPosArray[t];
  123.     }
  124. b=(a[rook]|a[queen])&MoveArray[rook][sq];
  125. while(b)
  126.     {
  127.     t=leadz(b);
  128.     CLEARBIT(b,t);
  129.     if(!(c[t]&blocker&NotBitPosArray[t]))
  130.     e|=BitPosArray[t];
  131.     }
  132. return e;
  133. }
  134.  
  135. BitBoard AttackXTo(short sq,short side)
  136. {
  137. BitBoard *a,b,*c,*d,e,blocker;
  138. short t;
  139. a=board.b[side];
  140. d=board.b[1^side];
  141. e=(a[knight]&MoveArray[knight][sq]);    
  142. e|=(a[king]&MoveArray[king][sq]);    
  143. c=FromToRay[sq];
  144. b=(a[pawn]&MoveArray[ptype[1^side]][sq]);
  145. blocker=board.blocker;
  146. blocker&=~(a[bishop]|a[queen]|d[bishop]|d[queen]|b);
  147. b|=(a[bishop]|a[queen])&MoveArray[bishop][sq];
  148. while(b)
  149.     {
  150.     t=leadz(b);
  151.     CLEARBIT(b,t);
  152.     if(!(c[t]&blocker&NotBitPosArray[t]))
  153.     e|=BitPosArray[t];
  154.     }
  155. b=(a[rook]|a[queen])&MoveArray[rook][sq];
  156. blocker=board.blocker;
  157. blocker&=~(a[rook]|a[queen]|d[rook]|d[queen]);
  158. while(b)
  159.     {
  160.     t=leadz(b);
  161.     CLEARBIT(b,t);
  162.     if(!(c[t]&blocker&NotBitPosArray[t]))
  163.     e|=BitPosArray[t];
  164.     }
  165. return e;
  166. }
  167.  
  168. BitBoard AttackFrom(short sq,short piece,short side)
  169. {
  170. switch(piece)
  171.     {
  172.     case pawn:
  173.         return(MoveArray[ptype[side]][sq]);
  174.     case knight:
  175.         return(MoveArray[knight][sq]);
  176.     case bishop:
  177.         return(BishopAttack(sq));
  178.     case rook:
  179.         return(RookAttack(sq));
  180.     case queen:
  181.         return(QueenAttack(sq));
  182.     case king:
  183.         return(MoveArray[king][sq]);
  184.     }
  185. return 0;
  186. }
  187.  
  188. BitBoard AttackXFrom(short sq,short side)
  189. {
  190. BitBoard *a,b,c,blocker;
  191. short piece,dir,blocksq;
  192. a=board.b[side];
  193. piece=cboard[sq];
  194. blocker=board.blocker;
  195. b=0;
  196. switch(piece)
  197.     {
  198.     case pawn:
  199.         b=MoveArray[ptype[side]][sq];
  200.         break;
  201.     case knight:
  202.         b=MoveArray[knight][sq];
  203.         break;
  204.     case bishop:
  205.     case queen:
  206.         blocker&=~(a[bishop]|a[queen]);
  207.         for(dir=raybeg[bishop];dir<rayend[bishop];dir++)
  208.             {
  209.             c=Ray[sq][dir]&blocker;
  210.             if(c==NULLBITBOARD) c=Ray[sq][dir];
  211.             else
  212.                 {
  213.                 blocksq=(BitPosArray[sq]>c?leadz(c):trailz(c));
  214.                 c=FromToRay[sq][blocksq];
  215.                 }
  216.             b|=c;
  217.             }
  218.         if(piece==bishop) break;
  219.         blocker=board.blocker;
  220.     case rook:
  221.         blocker&=~(a[rook]|a[queen]);
  222.         for(dir=raybeg[rook];dir<rayend[rook];dir++)
  223.             {
  224.             c=Ray[sq][dir]&blocker;
  225.             if(c==NULLBITBOARD) c=Ray[sq][dir];
  226.             else
  227.                 {
  228.                 blocksq=(BitPosArray[sq]>c?leadz(c):trailz(c));
  229.                 c=FromToRay[sq][blocksq];
  230.                 }
  231.             b|=c;
  232.             }
  233.         break;
  234.     case king:
  235.         b=MoveArray[king][sq];
  236.         break;
  237.     } 
  238. return b;
  239. }
  240.  
  241. short PinnedOnKing(short sq,short side)
  242. {
  243. short xside,KingSq,dir,sq1;
  244. BitBoard b,blocker;
  245. KingSq=board.king[side];
  246. if((dir=directions[KingSq][sq])==-1) return false;
  247. xside=1^side;
  248. blocker=board.blocker;
  249. if(FromToRay[KingSq][sq]&NotBitPosArray[sq]&blocker) return false;
  250. b=(Ray[KingSq][dir]^FromToRay[KingSq][sq])&blocker;
  251. if(b==NULLBITBOARD) return false;
  252. sq1=(sq>KingSq?leadz(b):trailz(b));
  253. if(dir<=3&&BitPosArray[sq1] &(board.b[xside][queen]|board.b[xside][bishop])) return true;
  254. if(dir>=4&&BitPosArray[sq1] &(board.b[xside][queen]|board.b[xside][rook])) return true;
  255. return false;
  256. }
  257.  
  258. void FindPins(BitBoard *pin)
  259. {
  260. short side,xside,sq,sq1;
  261. BitBoard b,c,e,f,t,*p;
  262. *pin=NULLBITBOARD;
  263. t=board.friends[white]|board.friends[black];
  264. for(side=white;side<=black;side++)
  265.     {
  266.     xside=1^side;
  267.     p=board.b[xside];
  268.     e=p[rook]|p[queen]|p[king];
  269.     e|=(p[bishop]|p[knight])&~Ataks[xside][0];
  270.     b=board.b[side][bishop];
  271.     while(b)
  272.         {
  273.         sq=leadz(b);
  274.         CLEARBIT(b,sq);
  275.         c=MoveArray[bishop][sq]&e;
  276.         while(c)
  277.             {
  278.             sq1=leadz(c);
  279.             CLEARBIT(c,sq1);
  280.             f=t&NotBitPosArray[sq]&FromToRay[sq1][sq];
  281.             if((board.friends[xside]&f)&&nbits(f)==1)
  282.             *pin|=f;
  283.             }
  284.         }
  285.     e=p[queen]|p[king];
  286.     e|=(p[rook]|p[bishop]|p[knight])&~Ataks[xside][0];
  287.     b=board.b[side][rook];
  288.     while(b)
  289.         {
  290.         sq=leadz(b);
  291.         CLEARBIT(b,sq);
  292.         c=MoveArray[rook][sq]&e;
  293.         while(c)
  294.             {
  295.             sq1=leadz(c);
  296.             CLEARBIT(c,sq1);
  297.             f=t&NotBitPosArray[sq]&FromToRay[sq1][sq];
  298.             if((board.friends[xside]&f)&&nbits(f)==1)
  299.             *pin|=f;
  300.             }
  301.         }
  302.     e=board.b[xside][king];
  303.     e|=(p[queen]|p[rook]|p[bishop]|p[knight])&~Ataks[xside][0];
  304.     b=board.b[side][queen];
  305.     while(b)
  306.         {
  307.         sq=leadz(b);
  308.         CLEARBIT(b,sq);
  309.         c=MoveArray[queen][sq]&e;
  310.         while(c)
  311.             {
  312.             sq1=leadz(c);
  313.             CLEARBIT(c,sq1);
  314.             f=t&NotBitPosArray[sq]&FromToRay[sq1][sq];
  315.             if((board.friends[xside]&f)&&nbits(f)==1)
  316.             *pin|=f;
  317.             }
  318.         }
  319.     }
  320. }
  321.  
  322. short MateScan(short side)
  323. {
  324. short KingSq,QueenSq,xside,sq;
  325. BitBoard b;
  326. xside=1^side;
  327. if(board.b[xside][queen]==0) return 0;
  328. KingSq=board.king[side];
  329. QueenSq=leadz(board.b[xside][queen]);
  330. b=QueenAttack(QueenSq)&MoveArray[king][KingSq];
  331. if(b==0) return 0;
  332. while(b)
  333.     {
  334.     sq=leadz(b);
  335.     CLEARBIT(b,sq);
  336.     if(AttackTo(sq,side)==board.b[side][king]&&AttackXTo(sq,xside)!=board.b[xside][queen])
  337.     return 1;
  338.     }
  339. return 0;
  340. }
  341.